package com.example.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Date 2022/3/7
 * @Created by Jonathan
 */
public class MiniArrayBlockingQueue implements BlockingQueue {

    private Lock lock = new ReentrantLock();
    private Condition full = lock.newCondition();
    private Condition empty = lock.newCondition();
    // 底层存储数据的数组
    private Object[] queues;
    private int size;
    private int count, putPtr, takePtr;


    // 初始化
    public MiniArrayBlockingQueue(int size) {
        this.size = size;
        this.queues = new Object[size];
    }

    @Override
    public void put(Object element) throws InterruptedException {
        lock.lock();
        try {
            if (count == size) full.await();
            this.queues[putPtr++] = element;
            count++;
            if (putPtr == size) putPtr = 0;
            empty.signal();
        } finally {
            lock.unlock();
        }

    }

    // 空不出 满不进
    @Override
    public Object take() throws InterruptedException {
        lock.lock();
        Object el = null;
        try {
            if (0 == count) empty.await();
            el = this.queues[takePtr++];
            count--;
            if (takePtr == size) takePtr = 0;
            full.signal();
            return el;
        } finally {
            lock.unlock();
        }
    }
}
